﻿using System;
using Shell.Build;

namespace Shell.Advanced
{
    public class ShellRegistrationRecorderExtension : IShellExtension
    {
        private ShellRegistrationRecorder recorder;

        public ShellRegistrationRecorderExtension()
        {
            this.recorder = new ShellRegistrationRecorder();
        }

        public Guid Identity
        {
            get { return IShellExtensionIdentities.ShellRegistrationHolderExtension; }
        }

        public virtual IShellRegistrationHolder ShellRegistrationHolder
        {
            get { return this.recorder; }
        }

        public ShellExtensionContext Context { get; private set; }

        public virtual void Initialize(ShellExtensionContext context)
        {
            this.Context = context;
            this.Context.TypeRegistered += this.Context_TypeRegistered;
            this.Context.InstanseRegistered += this.Context_InstanseRegistered;
        }

        public void Dispose()
        {
            this.Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Context_InstanseRegistered(object sender, InstanceRegisterEventArgs e)
        {
            var from = e.From ?? e.Instance.GetType();
            object identity = new BuildIdentity(from, e.Name);
            this.recorder.Record(identity);
        }

        protected virtual void Context_TypeRegistered(object sender, TypeRegisterEventArgs e)
        {
            if (e.From != null)
            {
                if (e.From.IsGenericTypeDefinition && e.To.IsGenericTypeDefinition)
                {
                    // TODO for generic type
                }
                else
                {
                    var identity = new BuildIdentity(e.From, e.Name);
                    this.recorder.Record(identity);
                }
            }
        }

        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                this.Context.TypeRegistered -= this.Context_TypeRegistered;
                this.Context.InstanseRegistered -= this.Context_InstanseRegistered;
                this.recorder = null;
                this.Context = null;
            }
        }
    }
}
